// inserting into a list
#include <iostream>
#include <list>
#include <vector>
#define ARRAY_SIZE(array) (sizeof((array))/sizeof((array[0])))
using namespace std;

void example1(){
    std::list<int> mylist;
  std::list<int>::iterator it;

  // set some initial values:
  for (int i=1; i<=5; ++i) mylist.push_back(i); // 1 2 3 4 5

  it = mylist.begin();
  ++it;       // it points now to number 2           ^

  mylist.insert (it,10);                        // 1 10 2 3 4 5

  // "it" still points to number 2                      ^
  mylist.insert (it,2,20);                      // 1 10 20 20 2 3 4 5

  --it;       // it points now to the second 20            ^

  std::vector<int> myvector (2,30);
  mylist.insert (it,myvector.begin(),myvector.end());
                                                // 1 10 20 30 30 20 2 3 4 5
                                                //                 
  std::cout << "mylist contains:";
  for (it=mylist.begin(); it!=mylist.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';
}

void example2(){ // how to use advance in iterator.
    std::list<int> mylist;
  std::list<int>::iterator it;

  // set some initial values:
  for (int i=1; i<=5; ++i) mylist.push_back(i); // 1 2 3 4 5

  it = mylist.begin();
  advance(it,2) ;      // it points now to number 2           ^
  
  mylist.insert(it,100);
  std::cout << "mylist contains:";
  for (it=mylist.begin(); it!=mylist.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';
}

void example3(){ // how to use "push front"
    std::list<int> mylist (2,100);         // two ints with a value of 100
    mylist.push_front (200);
    mylist.push_front (300);

    std::cout << "mylist contains:";
    for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
      std::cout << ' ' << *it;

    std::cout << '\n';
}

void example4(){ // how to use remove
    int myints[]= {17,89,7,89,14};
    //std::list<int> mylist (myints,myints+5);
    //std::list<int> mylist (myints,myints + sizeof(myints)/sizeof(int));
    std::list<int> mylist (myints,myints + ARRAY_SIZE(myints));
    
    mylist.remove(89);

    std::cout << "mylist contains:";
    for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
    std::cout << ' ' << *it;
    std::cout << '\n';
    
}

void example5(){ // how to use erase
    std::list<int> mylist;
  std::list<int>::iterator it1,it2;

  // set some values:
  for (int i=1; i<10; ++i) mylist.push_back(i*10);

                              // 10 20 30 40 50 60 70 80 90
  it1 = it2 = mylist.begin(); // ^^
  advance (it2,6);            // ^                 ^
  ++it1;                      //    ^              ^

  it1 = mylist.erase (it1);   // 10 30 40 50 60 70 80 90
                              //    ^           ^

  it2 = mylist.erase (it2);   // 10 30 40 50 60 80 90
                              //    ^           ^

  //++it1;                      //       ^        ^
  //--it2;                      //       ^     ^
  
  it1 = mylist.begin();
  it2 = mylist.begin();
  
  advance(it2,3);
  mylist.erase (it1,it2);     // 10 30 60 80 90
                              //        ^

  std::cout << "mylist contains:";
  for (it1=mylist.begin(); it1!=mylist.end(); ++it1)
    std::cout << ' ' << *it1;
  std::cout << '\n';
    
}

void example6(){// how to use back
    std::list<int> mylist;

  mylist.push_back(10);

  while (mylist.back() != 0)
  {
    mylist.push_back ( mylist.back() -1 );
  }

  std::cout << "mylist contains:";
  for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end() ; ++it)
    std::cout << ' ' << *it;

  std::cout << '\n';
}

void example7(){ // how to use pop back
    std::list<int> mylist;
  int sum (0);
  mylist.push_back (100);
  mylist.push_back (200);
  mylist.push_back (300);

  while (!mylist.empty())
  {
    sum+=mylist.back();
    mylist.pop_back();
  }

  std::cout << "The elements of mylist summed " << sum << '\n';
}

void example8(){ // how to use pop front
    std::list<int> mylist;
  mylist.push_back (100);
  mylist.push_back (200);
  mylist.push_back (300);

  std::cout << "Popping out the elements in mylist:";
  while (!mylist.empty())
  {
    std::cout << ' ' << mylist.front();
    mylist.pop_front();
  }

  std::cout << "\nFinal size of mylist is " << mylist.size() << '\n';
}

void example9(){ // how to use reverse
    std::list<int> mylist;

    for (int i=1; i<10; ++i) mylist.push_back(i);

    mylist.reverse();

    std::cout << "mylist contains:";
    for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); it++)
    std::cout << ' ' << *it;

    std::cout << '\n';

}

void example10(){ // how to use sort
    std::list<int> mylist;
  std::list<int>::iterator it;
  mylist.push_back (4);
  mylist.push_back (8);
  mylist.push_back (3);
  mylist.push_back (3);
  mylist.push_back (1);
  mylist.push_back (3);
  mylist.push_back (5);
  mylist.push_back (9);
  mylist.push_back (3);
  
  mylist.sort();

  /*std::cout << "mylist contains:";
  for (it=mylist.begin(); it!=mylist.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';*/

  //mylist.sort(compare_nocase);

  std::cout << "mylist contains:";
  for (it=mylist.begin(); it!=mylist.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';
}
